package com.example.youdu.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.youdu.dto.CallBackDto;
import com.example.youdu.service.IAccessTokenService;
import com.google.gson.JsonObject;
import im.youdu.sdk.client.AppClient;
import im.youdu.sdk.encrypt.AESCrypto;
import im.youdu.sdk.entity.ReceiveAuth;
import im.youdu.sdk.entity.YDApp;
import im.youdu.sdk.exception.GeneralEntAppException;
import im.youdu.sdk.util.Helper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/********************************************************************************
 ** author： caowenhao
 ** date：2024年07月24日 19:44
 ** description&desc：
 *********************************************************************************/
@Controller
@RequestMapping("/callback/")
public class CallBackController {

    @Autowired
    private IAccessTokenService tokenService;

    @Value("${yd.buin}")
    private int buin ; // 请填写企业总机号码


    @Value("${yd.appName}")
    private String appName ; //请填写消息审计名称
    @Value("${yd.appId}")
    private String appId ; // 请填写消息审计AppId
    @Value("${yd.appToken}")
    private String appToken ; //请填写消息审计token
    @Value("${yd.appAesKey}")
    private String appAesKey ; // 请填写消息审计EncodingAesKey



    /**
     * 查询投标保函申请列表
     */
    @PostMapping("/login")
    @ResponseBody
    public String login(HttpServletRequest request) throws Exception
    {
        JSONObject result = new JSONObject();
        CallBackDto callBackDto = this.receive(request);
        if(callBackDto == null){
            result.put("errcode", 300002);
            result.put("errmsg", "");
            result.put("encrypt", "");
        }
        System.out.println("CallBackController.login: "+JSONObject.toJSONString(callBackDto));
        JSONObject jsonObject = tokenService.login(callBackDto);
        String code = jsonObject.getString("code");
        JSONObject data = jsonObject.getJSONObject("data");
//        String code= "100001";
//        String state = "1";
        if("100001".equals(code)){
            String state = data.getString("state");
            if("1".equals(state)){
                result.put("errcode", 0);
                result.put("errmsg", "");
                result.put("encrypt", "");
            }else{
                result.put("errcode", 300002);
                result.put("errmsg", "");
                result.put("encrypt", "");
            }

        }else{
            result.put("errcode", 300002);
            result.put("errmsg", "");
            result.put("encrypt", "");
        }
        System.out.println("---返回值---"+result.toJSONString());
        return result.toString();
    }

    @GetMapping("/loginget")
    @ResponseBody
    public String loginget(CallBackDto callBackDto)throws Exception
    {
        JSONObject result = new JSONObject();
        JSONObject jsonObject = tokenService.login(callBackDto);
        String code = jsonObject.getString("code");
        JSONObject data = jsonObject.getJSONObject("data");

        if("100001".equals(code)){
            String state = data.getString("state");
            if("1".equals(state)){
                result.put("errcode", 0);
                result.put("errmsg", "");
                result.put("encrypt", "");
            }else{
                result.put("errcode", 300002);
                result.put("errmsg", "");
                result.put("encrypt", "");
            }

        }else{
            result.put("errcode", 300002);
            result.put("errmsg", "");
            result.put("encrypt", "");
        }
        System.out.println("---返回值---"+result.toJSONString());
        return result.toString();
    }

    @GetMapping("/ceshi")
    @ResponseBody
    public String ceshi()throws Exception
    {
//        String appId ="sysOrgAssistant" ;
//        String encodingAesKey = "M3KaiF2aUsIE3cOP5ICw/GGu5ZEUSHlip3gb2BFG9dk=";
        String encrypt = "HukrGRMfuoeei+bQM3eD0qkx0muEYCD7S6vN+VjgW9uMzq0j6GaJ58x0qAYrc3lDc7fbs4Nomym3j+00ZTzpV5lv+BaGx1kEcJODN+/o+laksGC0gy25xDEa1fUU9b90xAEGtRdajKmpdU8NrsFmOKcHd9ZHSf20E0NPPYfbmmnxmpdQojjRlA6ksED8w4suYURkGawUywingQMt62CESZmur4UScZ4Ag0LaqdbkVkHs9eFUmoLXnuCmzNeSaPoCTKeGxfAlZMm60368jHt+povWuHan0gPXC4GQJd/TROU=";
//        AESCrypto aesCrypto = new AESCrypto(appId,encodingAesKey);
//        byte[] data = aesCrypto.decrypt(xml);
//        String decryptResult = Helper.utf8String(data);
        YDApp ydApp = new YDApp(buin, "", appName, appId, appToken, appAesKey);
        AppClient appClient = new AppClient(ydApp);
        ReceiveAuth msg = appClient.decryptAuth(encrypt);
        return msg.toString();
    }

    private CallBackDto receive(HttpServletRequest request) throws IOException {
        YDApp ydApp = new YDApp(buin, "", appName, appId, appToken, appAesKey);
        System.out.println("进入验证====："+ydApp.toString());
        //请求参数
        Map<String, String> map = new HashMap<>(3);
        Enumeration<String> keys = request.getParameterNames();
        while (keys.hasMoreElements()) {
            String key = keys.nextElement();
            map.put(key, request.getParameter(key));
        }
        //请求数据体
        InputStream in = request.getInputStream();
        byte[] reqData = Helper.readInputStream(in);
        AppClient appClient = new AppClient(ydApp);
        CallBackDto callBackDto =null;
        try {
            //处理接收到的数据体
            callBackDto = handleReceive(map, reqData, appClient, ydApp);

        } catch (GeneralEntAppException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //返回接收成功，不返回接收成功会重复收到消息推送
        return callBackDto;
    }

    /**
     * 解密消息体
     * @param reqParam  请求参数
     * @param reqData 请求数据体
     * @param appClient 客户端
     * @param app 客户端实体
     * @throws GeneralEntAppException 异常
     * @throws IOException 异常
     */
    private CallBackDto  handleReceive(Map<String, String> reqParam, byte[] reqData, AppClient appClient, YDApp app) throws GeneralEntAppException, IOException {
        String content = Helper.utf8String(reqData);
        JsonObject reqJson = Helper.parseJson(content);
        int buin = Helper.getInt("toBuin", reqJson);
        String appId = Helper.getString("toApp", reqJson);
        String encrypt = Helper.getString("encrypt", reqJson);
        if (buin != app.getBuin()) {
            System.out.println(String.format("[%s][error] from buin %d is unequal local buin %d", app.getAppName(), buin, app.getBuin()));
            throw  new RuntimeException("buin is not equal");
        }
        if (!appId.equals(app.getAppId())) {
            System.out.println(String.format("[%s][error] from appId %s is unequal local appId %s", app.getAppName(), appId, app.getAppId()));
            throw  new RuntimeException("appId is not equal");
        }
        boolean fromYD = Helper.signatureIsValid(reqParam, app.getToken(), encrypt);
        if (!fromYD) {
            System.out.println(String.format("[%s][error] signature is invalid", app.getAppName()));
            throw  new RuntimeException("signature is invalid");
        }
        ReceiveAuth msg = appClient.decryptAuth(encrypt);
        CallBackDto callBackDto = new CallBackDto();
        if (msg != null) {
            callBackDto.setFromUser(msg.getFromUser());
            callBackDto.setPasswd(msg.getPasswd());
        }
//        receive(msg);
        return callBackDto;
    }
}